#include <windows.h>

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "ui_translate.h"
#include "ui_scaledialog.h"
#include "ui_rotatedialog.h"
#include "ui_rotatearbitraryaxisdialog.h"
#include "ui_addlinedialog.h"
#include "ui_reflectdialog.h"

#include "point3d.h"

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), drawer(new Drawer(this))
{
    ui->setupUi(this);
    this->statusBar()->setSizeGripEnabled(false);

    drawer->setDimensions(639, 438);

    on_actionCavalier_30_triggered();
    setCentralWidget(drawer);
}

MainWindow::~MainWindow()
{
    delete ui;
}

/* Menu Object */
void MainWindow::on_actionAdd_line_triggered()
{
    QDialog *dialog = new QDialog;
    Ui::AddLineDialog uiDialog;
    uiDialog.setupUi(dialog);

    if(dialog->exec() == QDialog::Accepted) {
        bool ok;

        qreal p1x = uiDialog.ponto1x->text().toDouble(&ok); if(!ok) return;
        qreal p1y = uiDialog.ponto1y->text().toDouble(&ok); if(!ok) return;
        qreal p1z = uiDialog.ponto1z->text().toDouble(&ok); if(!ok) return;

        qreal p2x = uiDialog.ponto2x->text().toDouble(&ok); if(!ok) return;
        qreal p2y = uiDialog.ponto2y->text().toDouble(&ok); if(!ok) return;
        qreal p2z = uiDialog.ponto2z->text().toDouble(&ok); if(!ok) return;

        drawer->addObjectLine(p1x,p1y,p1z, p2x,p2y,p2z);
    }
    delete(dialog);
}

void MainWindow::on_actionCube_triggered()
{
    drawer->getCube();
    drawer->repaint();
}

void MainWindow::on_actionPyramid_triggered()
{
    drawer->getStar();
    drawer->repaint();
}

void MainWindow::on_actionErase_triggered()
{
    drawer->clearObject();
    drawer->repaint();
}

/* Menu Projections */
void MainWindow::on_actionCabinet_30_triggered()
{
    drawer->setProjection(30, 0.5);    
    ui->actionCabinet_30->setChecked(true);
    ui->actionCabinet_45->setChecked(false);
    ui->actionCavalier_30->setChecked(false);
    ui->actionCavalier_45->setChecked(false);
    drawer->repaint();
}

void MainWindow::on_actionCabinet_45_triggered()
{
    drawer->setProjection(45, 0.5);    
    ui->actionCabinet_30->setChecked(false);
    ui->actionCabinet_45->setChecked(true);
    ui->actionCavalier_30->setChecked(false);
    ui->actionCavalier_45->setChecked(false);
    drawer->repaint();

}

void MainWindow::on_actionCavalier_30_triggered()
{
    drawer->setProjection(30, 1.0);    
    ui->actionCabinet_30->setChecked(false);
    ui->actionCabinet_45->setChecked(false);
    ui->actionCavalier_30->setChecked(true);
    ui->actionCavalier_45->setChecked(false);
    drawer->repaint();
}

void MainWindow::on_actionCavalier_45_triggered()
{
    drawer->setProjection(45, 1.0);    
    ui->actionCabinet_30->setChecked(false);
    ui->actionCabinet_45->setChecked(false);
    ui->actionCavalier_30->setChecked(false);
    ui->actionCavalier_45->setChecked(true);
    drawer->repaint();
}

/* Menu Transformations */
void MainWindow::on_actionTranslate_triggered()
{
    QDialog *dialog = new QDialog;
    Ui::TranslateDialog uiDialog;
    uiDialog.setupUi(dialog);

    if(dialog->exec() == QDialog::Accepted) {
        bool ok;
        qreal x = uiDialog.lineEditX->text().toDouble(&ok);
        qreal y = uiDialog.lineEditY->text().toDouble(&ok);
        qreal z = uiDialog.lineEditZ->text().toDouble(&ok);
        Point3D p(x,y,z);
        drawer->translate(p);
    }
    delete(dialog);
}

void MainWindow::on_actionScale_triggered()
{
    QDialog *dialog = new QDialog;
    Ui::ScaleDialog uiDialog;
    uiDialog.setupUi(dialog);

    if(dialog->exec() == QDialog::Accepted) {
        bool ok;

        qreal sX = uiDialog.fatorDeEscalonamentoX->text().toDouble(&ok);
        if(!ok) return;

        qreal sY = uiDialog.fatorDeEscalonamentoY->text().toDouble(&ok);
        if(!ok) return;

        qreal sZ = uiDialog.fatorDeEscalonamentoZ->text().toDouble(&ok);
        if(!ok) return;

        qreal rX = uiDialog.pontoDeRerecenciaX->text().toDouble(&ok);
        if(!ok) return;

        qreal rY = uiDialog.pontoDeReferenciaY->text().toDouble(&ok);
        if(!ok) return;

        qreal rZ = uiDialog.pontoDeReferenciaZ->text().toDouble(&ok);
        if(!ok) return;

        Point3D sP(sX,sY,sZ);
        Point3D rP(rX,rY,rZ);

        drawer->scale(sP,rP);
    }
    delete(dialog);
}

void MainWindow::on_actionRotate_triggered()
{
    QDialog *dialog = new QDialog;
    Ui::RotateDialog uiDialog;
    uiDialog.setupUi(dialog);

    if(dialog->exec() == QDialog::Accepted) {
        bool ok;

        qreal angle = uiDialog.angle->text().toDouble(&ok);
        if(!ok) return;

        int axis = uiDialog.axis->currentIndex();

        qreal x = uiDialog.referenceX->text().toDouble(&ok);
        if(!ok) return;

        qreal y = uiDialog.referenceY->text().toDouble(&ok);
        if(!ok) return;

        qreal z = uiDialog.referenceZ->text().toDouble(&ok);
        if(!ok) return;

        Point3D p(x,y,z);

        drawer->rotate(angle,axis,p);
    }
    delete(dialog);
}

void MainWindow::on_actionRotate_About_Arbitrary_Axis_triggered()
{
    QDialog *dialog = new QDialog;
    Ui::RotateArbitraryAxisDialog uiDialog;
    uiDialog.setupUi(dialog);

    if(dialog->exec() == QDialog::Accepted) {
        bool ok;
        qreal angle = uiDialog.angle->text().toDouble(&ok);

        qreal p1x = uiDialog.p1X->text().toDouble(&ok); if(!ok) return;
        qreal p1y = uiDialog.p1Y->text().toDouble(&ok); if(!ok) return;
        qreal p1z = uiDialog.p1Z->text().toDouble(&ok); if(!ok) return;

        qreal p2x = uiDialog.p2X->text().toDouble(&ok); if(!ok) return;
        qreal p2y = uiDialog.p2Y->text().toDouble(&ok); if(!ok) return;
        qreal p2z = uiDialog.p2Z->text().toDouble(&ok); if(!ok) return;

        Point3D p1(p1x,p1y,p1z);
        Point3D p2(p2x,p2y,p2z);
        drawer->rotateAboutArbitraryAxis(angle, p1, p2);
    }
    delete(dialog);
}

void MainWindow::on_actionReflect_triggered()
{
    QDialog *dialog = new QDialog;
    Ui::ReflectDialog uiDialog;
    uiDialog.setupUi(dialog);

    if(dialog->exec() == QDialog::Accepted) {
        int a = uiDialog.axis->currentIndex();
        qDebug() << a;
        drawer->reflect(a);
    }
    delete(dialog);
}

/* Menu Animations */
void MainWindow::on_actionRotation_triggered()
{
    Point3D p1(0,0,0);
    Point3D p2(0,0,-50);

    for(int i = 0; i<360; i++) {
        qreal angle = 1;
        drawer->rotateAboutArbitraryAxis(angle, p1, p2);
        drawer->repaint();
        Sleep(7);
    }

    Point3D tmp(0,0,-50);
    int eixo = 1;
    for(int i = 0; i<360; i++) {
        qreal angle = 1;
        drawer->rotate(angle,eixo,tmp);
        drawer->repaint();
        Sleep(7);
    }
}

void MainWindow::on_actionScaling_triggered()
{

    Point3D scale(1.1,1,1);
    Point3D referece(0,0,0);

    for(int i = 0; i<10; i++) {
        drawer->scale(scale,referece);
        drawer->repaint();
        Sleep(50);
    }

    scale.setX(0.9);
    for(int i = 0; i<9; i++) {
        drawer->scale(scale,referece);
        drawer->repaint();
        Sleep(50);
    }

    scale.setX(1);
    scale.setY(1.1);
    for(int i = 0; i<10; i++) {
        drawer->scale(scale,referece);
        drawer->repaint();
        Sleep(50);
    }

    scale.setY(0.9);
    for(int i = 0; i<9; i++) {
        drawer->scale(scale,referece);
        drawer->repaint();
        Sleep(50);
    }
}

void MainWindow::on_actionTranslating_triggered()
{
    Point3D p(-2,-2,0);
    for(int i = 0; i<55; i++) {
        drawer->translate(p);
        drawer->repaint();
        Sleep(20);
    }

    p.setX(-2);
    p.setY(2);
    for(int i = 0; i<55; i++) {
        drawer->translate(p);
        drawer->repaint();
        Sleep(20);
    }

    p.setX(2);
    p.setY(2);
    for(int i = 0; i<55; i++) {
        drawer->translate(p);
        drawer->repaint();
        Sleep(20);
    }

    p.setX(2);
    p.setY(-2);
    for(int i = 0; i<55; i++) {
        drawer->translate(p);
        drawer->repaint();
        Sleep(20);
    }
}
